package cn.iocoder.yudao.module.erp.service.dp;

import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.erp.controller.admin.common.LocalDateAdapter;
import cn.iocoder.yudao.module.erp.controller.admin.common.LocalDateTimeAdapter;
import cn.iocoder.yudao.module.erp.controller.admin.dispatchvehicle.vo.DispatchVehicleSaveReqVO;
import cn.iocoder.yudao.module.erp.controller.admin.dp.dpdn.vo.DpDnPageReqVO;
import cn.iocoder.yudao.module.erp.controller.admin.dp.dpdn.vo.DpDnSaveReqVO;
import cn.iocoder.yudao.module.erp.controller.admin.dp.vo.DpSaveReqVO;
import cn.iocoder.yudao.module.erp.dal.dataobject.dispatchvehicle.DispatchVehicleDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.dp.DpDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.dp.DpDnDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.dpitem.DpItemDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.dpitem.DpItemDnDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.dplist.DpEastListDnDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.dplist.DpWestListDnDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.supplierfleet.SupplierFleetDO;
import cn.iocoder.yudao.module.erp.dal.mysql.dispatchvehicle.DispatchVehicleMapper;
import cn.iocoder.yudao.module.erp.dal.mysql.dp.DpMapper;
import cn.iocoder.yudao.module.erp.dal.mysql.dp.DpDnMapper;
import cn.iocoder.yudao.module.erp.dal.mysql.dpitem.DpItemDnMapper;
import cn.iocoder.yudao.module.erp.dal.mysql.dpeast.DpEastListDnMapper;
import cn.iocoder.yudao.module.erp.dal.mysql.dpwest.DpWestListDnMapper;
import javax.annotation.Resource;

import cn.iocoder.yudao.module.erp.dal.mysql.supplierfleet.SupplierFleetMapper;
import com.alibaba.fastjson.JSONObject;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import org.springframework.transaction.annotation.Transactional;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.*;

/**
 * ERP东宁制单 Service 实现类
 * @author 天使管理员
 */
@Service
@Validated
public class DpDnServiceImpl implements DpDnService {

    @Resource
    private DpDnMapper dpDnMapper;
    @Resource
    private DpItemDnMapper dpItemDnMapper;
    @Resource
    private DpEastListDnMapper dpEastListDnMapper;
    @Resource
    private DpWestListDnMapper dpWestListDnMapper;
    @Resource
    private DispatchVehicleMapper dispatchVehicleMapper;
    @Resource
    private DpServiceImpl dpServiceImpl;
    @Resource
    private DpMapper dpMapper;
    @Resource
    private SupplierFleetMapper supplierFleetMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String createDpDn(DpDnSaveReqVO createReqVO) {
        // 插入
        DpDnDO dpDn = BeanUtils.toBean(createReqVO, DpDnDO.class);
        dpDnMapper.insert(dpDn);
        // 插入子表
        createDpItemDnList(dpDn.getId(), createReqVO.getDpItemDns());
        createDpEastListDnList(dpDn.getId(), createReqVO.getDpEastListDns());
        createDpWestListDnList(dpDn.getId(), createReqVO.getDpWestListDns());
        createDispatchVehicle(createReqVO.getDispatchVehicleDOS());
        // 返回
        return dpDn.getId();
    }

//    @Override
//    public Boolean configCar(String dispatchNumber, List<DispatchorderitemDnSaveReqVO> createReqVO) {
////        List<Long> itemIds = dpItemDnMapper.selectListByNos(ids);
//        List<DispatchorderitemDnDO> dispatchorderitemDnDOS = new ArrayList<>();
//        List<Long> ids = createReqVO.stream().map(DispatchorderitemDnSaveReqVO::getId).collect(Collectors.toList());
//        dispatchorderitemDnMapper.deleteByItemIds(ids);
//        for (int i = 0; i < createReqVO.size(); i++) {
//            DispatchorderitemDnDO dispatchorderitemDnDO = new DispatchorderitemDnDO();
//            dispatchorderitemDnDO.setDispatchNumber(dispatchNumber);
//            dispatchorderitemDnDO.setItemId(createReqVO.get(i).getId());
//            dispatchorderitemDnDO.setNo(createReqVO.get(i).getNo());
//            dispatchorderitemDnDOS.add(dispatchorderitemDnDO);
//        }
//        return dispatchorderitemDnMapper.insertBatch(dispatchorderitemDnDOS);
//    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateDpDn(DpDnSaveReqVO updateReqVO) {
        // 更新
        DpDnDO updateObj = BeanUtils.toBean(updateReqVO, DpDnDO.class);
        dpDnMapper.updateById(updateObj);
        // 更新子表
        updateDpItemDnList(updateReqVO.getId(), updateReqVO.getDpItemDns());
        updateDpEastListDnList(updateReqVO.getId(), updateReqVO.getDpEastListDns());
        updateDpWestListDnList(updateReqVO.getId(), updateReqVO.getDpWestListDns());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteDpDn(String id) {
        // 删除
        dpDnMapper.deleteById(id);
        // 删除子表
        deleteDpItemDnByNo(id);
        deleteDpEastListDnByNo(id);
        deleteDpWestListDnByNo(id);
    }

    @Override
    public DpDnDO getDpDn(String id) {
        return dpDnMapper.selectById(id);
    }

    @Override
    public PageResult<DpDnDO> getDpDnPage(DpDnPageReqVO pageReqVO) {
        return dpDnMapper.getDpDnPage(pageReqVO);
    }


    @Override
    public PageResult<DpDnDO> dpDnOuterList(DpDnPageReqVO pageReqVO) {
        return dpDnMapper.selectRemCountNoZeroPage(pageReqVO);
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void dpDnOutStroe(DispatchVehicleSaveReqVO createReqVO) {
        List<DpDnDO> dpDnDOList= createReqVO.getDpDnDOList();
        //出库到国外仓更新总制单表出库状态为1
        Integer isForeign = createReqVO.getDest() > 7 ? 1 : 0;
        List<DpDO> dpList = new ArrayList<>();
        //防止修改总制单其他字段数据，只修改相应字段
        for (DpDnDO dpDO : dpDnDOList) {
            DpDO dp = new DpDO();
            dp.setId(dpDO.getId());
            dp.setInventoryStatus(1);
            dp.setIsForeign(isForeign);
            dpList.add(dp);
        }
        dpMapper.updateBatch(dpList);
        //修改运表单数据
        for (DpDnDO dpDnDO : dpDnDOList) {
            //设置剩余件数 = 剩余总件数 - 出库件数
            Integer outCount = dpDnDO.getOutCount();
            int remCount = dpDnDO.getRemCount() - (outCount == null ? 0 : outCount);
            if (remCount < 0) {
                throw exception(DP_COUNT_OUTOF_MAX);
            }else {
                dpDnDO.setRemCount(remCount);
            }
            //设置剩余体积 = 剩余总体积 - 出库体积
            Double outVolume = dpDnDO.getOutVolume();
            double remVolume = dpDnDO.getRemVolume() - (outVolume == null ? 0 : outVolume);
            if (remVolume < 0) {
                throw exception(DP_VOLUME_OUTOF_MAX);
            }else {
                dpDnDO.setRemVolume(remVolume);
            }
            //设置剩余重量 = 剩余总重量 - 出库重量
            Double outWeight = dpDnDO.getOutWeight();
            double remWeight = dpDnDO.getRemWeight() - (outWeight == null ? 0 : outWeight);
            if (remWeight < 0) {
                throw exception(DP_WEIGHT_OUTOF_MAX);
            }else {
                dpDnDO.setRemWeight(remWeight);
            }
        }

        //批量修改制单数据
        dpDnMapper.updateById(dpDnDOList);

        //往对应仓库插入数据
//        Integer dest = createReqVO.getDest();
//        List<DpDnDO> dps = new ArrayList<>();
//        for (DpDnDO dpDnDO : dpDnDOList) {
//            dpDnDO.setInventoryStatus(1);
//            dpDnDO.setRemCount(dpDnDO.getOutCount());
//            dpDnDO.setRemVolume(dpDnDO.getOutVolume());
//            dpDnDO.setRemWeight(dpDnDO.getOutWeight());
//            dps.add(dpDnDO);
//        }
//        List<DpDO> dpDOS = BeanUtils.toBean(dps, DpDO.class);
//        dpServiceImpl.insertDpByDest(dest,dpDOS);

        //处理配车表数据
        List<DispatchVehicleDO> dispDOs = new ArrayList<DispatchVehicleDO>();
        for (DpDnDO dpDnDO : dpDnDOList) {
            DispatchVehicleDO vehicleDO = BeanUtils.toBean(createReqVO, DispatchVehicleDO.class);
            //处理车数据
            vehicleDO.setDpId(dpDnDO.getId());
            vehicleDO.setNo(dpDnDO.getNo());
            vehicleDO.setDispatchNumber(createReqVO.getDispatchNumber());
            vehicleDO.setInventoryStatus(1);
            // 使用 Gson 将 dpYwDO 转换为 JSON 字符串
            Gson gson = new GsonBuilder()
                    .registerTypeAdapter(LocalDate.class, new LocalDateAdapter()) // 注册 LocalDate 适配器
                    .registerTypeAdapter(LocalDateTime.class, new LocalDateTimeAdapter())  // 跳过 LocalDateTime 字段
                    .create();
            String dpDataJson = gson.toJson(dpDnDO);  // LocalDateTime 字段会被跳过
            // 设置 JSON 字符串到 createReqVO 的 dpData 字段
            vehicleDO.setDpData(dpDataJson);
            dispDOs.add(vehicleDO);
        }
        // 批量插入配车数据
        dispatchVehicleMapper.insertBatch(dispDOs);

        //插入数据到供应商车队
        List<DispatchVehicleDO> supplierList = createReqVO.getSupplierInfo();
        String dispatchNumber = createReqVO.getDispatchNumber();
        String department = createReqVO.getDepartment();
        //处理时间
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String formattedDate = sdf.format(new Date());
        createReqVO.setDate(formattedDate);
        SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd");
        String recordDate = sdf2.format(new Date());
        createReqVO.setRecordDate(recordDate);
        createReqVO.setDpDnDOList(null);
        createReqVO.setSupplierInfo(null);
        List<SupplierFleetDO> fleetDOS = new ArrayList<>();
        for (DispatchVehicleDO supplierInfo : supplierList) {
            String fleet = supplierInfo.getFleet();
            if (fleet == null || fleet.trim().equals("")) {
                continue;
            }
            SupplierFleetDO supplierFleetDO = new SupplierFleetDO();
            supplierFleetDO.setType(1);
            supplierFleetDO.setCategory(supplierInfo.getCategory());
            supplierFleetDO.setName(supplierInfo.getSupplier());
            supplierFleetDO.setFleet(fleet);
            supplierFleetDO.setTotalAmount(supplierInfo.getExpense());
            //出库设置币种
            supplierFleetDO.setCurrencyType(supplierInfo.getCurrencyType());
            supplierFleetDO.setRemark(dispatchNumber);
            supplierFleetDO.setDepartment(department);

            // 处理info字段
            Gson gson = new GsonBuilder()
                    .registerTypeAdapter(LocalDate.class, new LocalDateAdapter()) // 注册 LocalDate 适配器
                    .registerTypeAdapter(LocalDateTime.class, new LocalDateTimeAdapter())  // 跳过 LocalDateTime 字段
                    .create();
            createReqVO.setCategory(supplierInfo.getCategory());
            createReqVO.setSupplier(supplierInfo.getSupplier());
            createReqVO.setFleet(fleet);
            createReqVO.setFare(supplierInfo.getFare());
            createReqVO.setExpense(supplierInfo.getExpense());
            createReqVO.setCurrencyType(supplierInfo.getCurrencyType());
            createReqVO.setRemark(dispatchNumber);
            createReqVO.setDepartment(department);
            String info = gson.toJson(createReqVO);
            supplierFleetDO.setInfo(info);
            fleetDOS.add(supplierFleetDO);
        }
        supplierFleetMapper.insertBatch(fleetDOS);
    }


    @Override
    public List<DispatchVehicleDO> dpDnEnterList(String dispatchNumber, Integer line, Integer inventoryStatus, Integer dest, String dpId) {
        return dispatchVehicleMapper.selectByDispatch(dispatchNumber, line, inventoryStatus, dest,dpId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void enterStroeDpDn(List<DispatchVehicleSaveReqVO> pageReqVO) {
        List<DispatchVehicleDO> list = BeanUtils.toBean(pageReqVO, DispatchVehicleDO.class);
        for (DispatchVehicleDO dispatchVehicleDO : list) {
            String dpData= dispatchVehicleDO.getDpData();
            JSONObject jsonObject = JSONObject.parseObject(dpData);
            DpDnDO dpDnDO = JSONObject.toJavaObject(jsonObject, DpDnDO.class);

            dpDnDO.setRemCount((Integer) jsonObject.get("outCount"));
            BigDecimal outVolume = jsonObject.getBigDecimal("outVolume");
            dpDnDO.setRemVolume(outVolume.doubleValue());
            BigDecimal outWeight = jsonObject.getBigDecimal("outWeight");
            dpDnDO.setRemWeight(outWeight.doubleValue());
            DpDnDO dpDnDO1 = dpDnMapper.selectById(dpDnDO.getId());
            dpDnDO.setInventoryStatus(2);
            if (dpDnDO1 != null) {
                dpDnDO.setRemCount(dpDnDO.getRemCount() + dpDnDO1.getRemCount());
                dpDnDO.setRemVolume(dpDnDO.getRemVolume() + dpDnDO1.getRemVolume());
                dpDnDO.setRemWeight(dpDnDO.getRemWeight() + dpDnDO1.getRemWeight());
                dpDnMapper.updateById(dpDnDO);
            } else {
                dpDnMapper.insert(dpDnDO);
            }

            dpMapper.enterDpStart(dpDnDO.getId());

            dispatchVehicleMapper.updateById(dispatchVehicleDO.setInventoryStatus(2));
        }
    }

    // ==================== 子表（ERP东宁制单货号详情） ====================

    @Override
    public List<DpItemDnDO> getDpItemDnListByNo(String no) {
        List<DpItemDnDO> dpItemDnDOS = dpItemDnMapper.selectListByNo(no);
        return dpItemDnDOS;
    }

    private void createDpItemDnList(String no, List<DpItemDnDO> list) {
        if (list == null || list.size() == 0){
            return;
        }
        list.forEach(o -> o.setNo(no));
        dpItemDnMapper.insertBatch(list);
    }

    private void updateDpItemDnList(String no, List<DpItemDnDO> list) {
        deleteDpItemDnByNo(no);
        createDpItemDnList(no, list);
    }

    private void deleteDpItemDnByNo(String no) {
        dpItemDnMapper.deleteByNo(no);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void examineDpDn(DpDnDO dpDnDO) {
        //删除总表里面的对应单据
        dpServiceImpl.deleteDp(dpDnDO.getId());
        if (dpDnDO.getStatus() == 1){
            convertdpDnToDp(dpDnDO);
            dpDnMapper.updateById(dpDnDO);
        } else {
            //修改当前仓库的单据状态
            dpDnMapper.updateById(dpDnDO);
            DpDnDO dnDO = dpDnMapper.selectById(dpDnDO.getId());
            dpMapper.insert(BeanUtils.toBean(dnDO, DpDO.class));
        }
    }

    // ==================== 子表（东宁东线清单） ====================

    @Override
    public List<DpEastListDnDO> getDpEastListDnListByNo(String no) {
        return dpEastListDnMapper.selectListByNo(no);
    }

    private void createDpEastListDnList(String no, List<DpEastListDnDO> list) {
        if (list == null || list.size() == 0){
            return;
        }
        list.forEach(o -> o.setNo(no));
        dpEastListDnMapper.insertBatch(list);
    }

    private void updateDpEastListDnList(String no, List<DpEastListDnDO> list) {
        deleteDpEastListDnByNo(no);
//		list.forEach(o -> o.setId(null)); // 解决更新情况下：1）id 冲突；2）updateTime 不更新
        createDpEastListDnList(no, list);
    }


    private void deleteDpEastListDnByNo(String no) {
        dpEastListDnMapper.deleteByNo(no);
    }


    // ==================== 子表（东宁西线清单） ====================
    @Override
    public List<DpWestListDnDO> getDpWestListDnListByNo(String no) {
        return dpWestListDnMapper.selectListByNo(no);
    }

    private void createDpWestListDnList(String no, List<DpWestListDnDO> list) {
        if (list == null || list.size() == 0){
            return;
        }
        list.forEach(o -> o.setNo(no));
        dpWestListDnMapper.insertBatch(list);
    }

    private void updateDpWestListDnList(String no, List<DpWestListDnDO> list) {
        deleteDpWestListDnByNo(no);
        createDpWestListDnList(no, list);
    }

    private void deleteDpWestListDnByNo(String no) {
        dpWestListDnMapper.deleteByNo(no);
    }


    private void createDispatchVehicle(List<DispatchVehicleDO> list) {
        if (list == null || list.size() == 0){
            return;
        }
        dispatchVehicleMapper.insertBatch(list);
    }

    // 将 GpDnSaveReqVO 转换为 DpSaveReqVO
    public void convertdpDnToDp(DpDnDO dpDnDO) {
        DpDnDO dpDo = dpDnMapper.selectById(dpDnDO.getId());
        //防止编辑时选了审核后插入总制单状态为1
        dpDo.setStatus(0);
        //设置剩余总件数
        dpDo.setRemCount(dpDo.getInCount());
        //设置剩余总体积
        dpDo.setRemVolume(dpDo.getInVolume());
        //设置剩余总重量
        dpDo.setRemWeight(dpDo.getWeight());
        //设置总欠款
        dpDo.setDebtTotal(dpDo.getTotalAmount());
        List<DpItemDnDO> dpItemDnDOList = dpItemDnMapper.selectListByNo(dpDnDO.getId());
        // 复制 DpDnSaveReqVO 中的属性到 DpSaveReqVO
        DpSaveReqVO createReqVO = BeanUtils.toBean(dpDo, DpSaveReqVO.class);
        createReqVO.setNotPoint(createReqVO.getCustomerRebate());
        if (createReqVO.getWriteOff() == 1){
            createReqVO.setNotWriteOff(createReqVO.getWriteExpenses());
        }
        List<DpItemDO> dpItems = BeanUtils.toBean(dpItemDnDOList, DpItemDO.class);
        //避免dp_item表的主键冲突
        dpItems.forEach(item -> item.setId(null));
        // 设置转换后的列表到 DpSaveReqVO
        createReqVO.setDpItems(dpItems);
        dpServiceImpl.createDp(createReqVO);
    }

}